package joc.internal.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import joc.internal.compiler.StaticCall;

public class AnnotationInstantiator {
	public static final StaticCall getAnnotationArrayAccessible = new StaticCall(AnnotationInstantiator.class,
			"getAnnotationArrayAccessible");

	public static <T extends Annotation> T getAnnotation(Class<T> annotationClass, final Object... values) {
		return getAnnotationArrayAccessible(annotationClass, values);
	}

	public static <T extends Annotation> T getAnnotationArrayAccessible(Class<T> annotationClass) {
		return getAnnotationArrayAccessible(annotationClass, new Object[] {});
	}

	@SuppressWarnings("unchecked")
	public static <T extends Annotation> T getAnnotationArrayAccessible(Class<T> annotationClass, final Object[] values) {
		final List<String> annotationMethods = new ArrayList<String>();
		for (Method annotationMethod : annotationClass.getDeclaredMethods()) {
			annotationMethods.add(annotationMethod.getName());
		}
		Collections.sort(annotationMethods);
		return (T) Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass },
				new InvocationHandler() {
					@Override
					public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
						return values[annotationMethods.indexOf(method.getName())];
					}
				});
	}
}
